/**
 * @filename:Contract3ServiceImpl 2024-01-01 00:00:00
 * @project com/lwl/blue  V1.0
 * Copyright(c) 2024 <a href=mailto:lanwenliang@yidianlife.com>蓝文良</a> Co. Ltd.
 * All right reserved.
 */
package com.lwl.blue.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lwl.blue.commont.base.JsonResult;
import com.lwl.blue.commont.base.PageParam;
import com.lwl.blue.commont.utils.UserContextUtil;
import com.lwl.blue.dao.Contract3Dao;
import com.lwl.blue.dao.ContractDetail3Dao;
import com.lwl.blue.entity.Contract3;
import com.lwl.blue.entity.ContractDetail3;
import com.lwl.blue.entity.PurchaseOrder;
import com.lwl.blue.entity.PurchaseOrderDetail;
import com.lwl.blue.service.Contract3Service;
import com.lwl.blue.service.PurchaseOrderService;
import com.lwl.blue.service.PurchaseOrderDetailService;
import com.lwl.blue.vo.LoginUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>自定义service实现写在这里</p>
 * 
 * <p>说明： 采购合同主表服务实现类</P>
 * @version: V1.0
 * @author: <a href=mailto:lanwenliang@yidianlife.com>蓝文良</a>
 * 
 */
@Slf4j
@Service
public class Contract3ServiceImpl extends ServiceImpl<Contract3Dao, Contract3> implements Contract3Service {

    @Autowired
    private Contract3Dao contract3Dao;
    
    @Autowired
    private ContractDetail3Dao contractDetail3Dao;
    
    @Autowired
    private PurchaseOrderService purchaseOrderService;
    
    @Autowired
    private PurchaseOrderDetailService purchaseOrderDetailService;

    @Override
    public JsonResult<Page<Contract3>> pages(PageParam<Contract3> pageParam) {
        try {
            Page<Contract3> page = new Page<>(pageParam.getPageNum(), pageParam.getPageSize());
            Page<Contract3> result = contract3Dao.pages(page, pageParam.getParam());
            return new JsonResult<Page<Contract3>>().success(result);
        } catch (Exception e) {
            log.error("分页查询采购合同失败", e);
            return new JsonResult<Page<Contract3>>().error("分页查询采购合同失败：" + e.getMessage());
        }
    }

    @Override
    public JsonResult<Contract3> getContractWithSupplier(String contractInnerId) {
        try {
            if (StringUtils.isEmpty(contractInnerId)) {
                return new JsonResult<Contract3>().error("合同内码不能为空");
            }
            Contract3 contract = contract3Dao.selectContractWithSupplier(contractInnerId);
            if (contract == null) {
                return new JsonResult<Contract3>().error("合同不存在");
            }
            return new JsonResult<Contract3>().success(contract);
        } catch (Exception e) {
            log.error("查询合同详情失败", e);
            return new JsonResult<Contract3>().error("查询合同详情失败：" + e.getMessage());
        }
    }

    @Override
    public JsonResult<List<Contract3>> getContractsByRelatedOrderNo(String relatedOrderNo) {
        try {
            if (StringUtils.isEmpty(relatedOrderNo)) {
                return new JsonResult<List<Contract3>>().error("关联订单号不能为空");
            }
            List<Contract3> contracts = contract3Dao.selectByRelatedOrderNo(relatedOrderNo);
            return new JsonResult<List<Contract3>>().success(contracts);
        } catch (Exception e) {
            log.error("根据关联订单号查询合同失败", e);
            return new JsonResult<List<Contract3>>().error("根据关联订单号查询合同失败：" + e.getMessage());
        }
    }

    @Override
    public JsonResult<List<Contract3>> getContractsByContractNoLike(String contractNo) {
        try {
            if (StringUtils.isEmpty(contractNo)) {
                return new JsonResult<List<Contract3>>().error("合同号不能为空");
            }
            List<Contract3> contracts = contract3Dao.selectByContractNoLike(contractNo);
            return new JsonResult<List<Contract3>>().success(contracts);
        } catch (Exception e) {
            log.error("根据合同号模糊查询合同失败", e);
            return new JsonResult<List<Contract3>>().error("根据合同号模糊查询合同失败：" + e.getMessage());
        }
    }

    @Override
    public JsonResult<BigDecimal> getTotalAmountByStatus(Integer contractStatus) {
        try {
            if (contractStatus == null) {
                return new JsonResult<BigDecimal>().error("合同状态不能为空");
            }
            BigDecimal totalAmount = contract3Dao.selectTotalAmountByStatus(contractStatus);
            return new JsonResult<BigDecimal>().success(totalAmount);
        } catch (Exception e) {
            log.error("统计合同总金额失败", e);
            return new JsonResult<BigDecimal>().error("统计合同总金额失败：" + e.getMessage());
        }
    }

    @Override
    public JsonResult<List<ContractDetail3>> getContractDetails(String contractInnerId) {
        try {
            if (StringUtils.isEmpty(contractInnerId)) {
                return new JsonResult<List<ContractDetail3>>().error("合同内码不能为空");
            }
            List<ContractDetail3> details = contractDetail3Dao.selectByContractInnerId(contractInnerId);
            return new JsonResult<List<ContractDetail3>>().success(details);
        } catch (Exception e) {
            log.error("查询合同明细失败", e);
            return new JsonResult<List<ContractDetail3>>().error("查询合同明细失败：" + e.getMessage());
        }
    }

    @Override
    public JsonResult<List<ContractDetail3>> getContractDetailsWithItem(String contractInnerId) {
        try {
            if (StringUtils.isEmpty(contractInnerId)) {
                return new JsonResult<List<ContractDetail3>>().error("合同内码不能为空");
            }
            List<ContractDetail3> details = contractDetail3Dao.selectDetailWithItem(contractInnerId);
            return new JsonResult<List<ContractDetail3>>().success(details);
        } catch (Exception e) {
            log.error("查询合同明细（含产品信息）失败", e);
            return new JsonResult<List<ContractDetail3>>().error("查询合同明细（含产品信息）失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Contract3> generateContractFromOrder(String relatedOrderNo) {
        try {
            if (StringUtils.isEmpty(relatedOrderNo)) {
                return new JsonResult<Contract3>().error("关联订单号不能为空");
            }
            
            // 查询订单信息
            QueryWrapper<PurchaseOrder> orderWrapper = new QueryWrapper<>();
            orderWrapper.eq("order_no", relatedOrderNo);
            orderWrapper.eq("is_delete", 0);
            PurchaseOrder order = purchaseOrderService.getOne(orderWrapper);
            
            if (order == null) {
                return new JsonResult<Contract3>().error("订单不存在");
            }
            
            if (order.getDocStatus() != 70) {
                return new JsonResult<Contract3>().error("只有执行中的订单才能生成合同");
            }
            
            // 检查是否已存在合同
            QueryWrapper<Contract3> contractWrapper = new QueryWrapper<>();
            contractWrapper.eq("related_order_no", relatedOrderNo);
            contractWrapper.eq("is_delete", 0);
            Contract3 existingContract = this.getOne(contractWrapper);
            
            if (existingContract != null) {
                return new JsonResult<Contract3>().error("该订单已生成合同，合同号：" + existingContract.getContractNo());
            }
            
            // 生成合同
            Contract3 contract = new Contract3();
            String contractInnerId = "HT" + System.currentTimeMillis();
            contract.setContractInnerId(contractInnerId);
            contract.setContractNo("HT" + relatedOrderNo);
            contract.setRelatedOrderNo(relatedOrderNo);
            contract.setLastBizDocNo(relatedOrderNo);
            contract.setBizDocCode("BIZ" + contract.getContractNo());
            Date currentDate = new Date();
            contract.setSignDate(currentDate);
            contract.setValidStartDate(currentDate);
            
            // 确保合同结束日期不早于开始日期
            Date orderEndDate = parseDate(order.getValidEndDate());
            if (orderEndDate != null && orderEndDate.after(currentDate)) {
                contract.setValidEndDate(orderEndDate);
            } else {
                // 如果订单结束日期为空或早于当前日期，设置为当前日期后30天
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(currentDate);
                calendar.add(Calendar.DAY_OF_MONTH, 30);
                contract.setValidEndDate(calendar.getTime());
            }
            contract.setDeliveryPlanType("FIXED_DATE");
            contract.setExpectedDeliveryDate(parseDate(order.getExpectedDeliveryDate()));
            contract.setPaymentTermsType("DELIVERY_AFTER_N");
            contract.setPaymentTermsDays(30);
            contract.setDocVersion("V1");
            contract.setVersionEffectiveTime(new Date());
            contract.setOriginalEffectiveDate(new Date());
            contract.setBizSource("INTERNAL");
            contract.setIntellectualPropertyClause("双方应保护对方的知识产权，不得泄露或盗用");
            contract.setConfidentialityClause("双方应对合作过程中的商业机密进行保密");
            contract.setLiabilityClause("任何一方违约应承担相应的法律责任");
            contract.setQuantity(1); // 默认数量为1，实际应该从订单明细汇总
            contract.setUnit("件");
            contract.setUnitPrice(order.getTotalAmount() != null ? order.getTotalAmount() : BigDecimal.ZERO);
            contract.setIsTempPrice("NO");
            contract.setTaxFreeUnitPrice(contract.getUnitPrice().multiply(new BigDecimal("0.87")));
            contract.setTaxFreeAmount(contract.getTaxFreeUnitPrice().multiply(new BigDecimal(contract.getQuantity())));
            contract.setTaxRate(new BigDecimal("13.00"));
            contract.setTaxAmount(contract.getTaxFreeAmount().multiply(contract.getTaxRate()).divide(new BigDecimal("100"), 2, java.math.RoundingMode.HALF_UP));
            contract.setTotalAmount(order.getTotalAmount() != null ? order.getTotalAmount() : BigDecimal.ZERO);
            contract.setContractStatus(70);
            contract.setRedFlag("NO");
            
            // 获取当前用户信息
            LoginUserInfo currentUser = UserContextUtil.getUser();
            if (currentUser != null) {
                contract.setCreatorId(currentUser.getId().toString());
                contract.setCreateUser(currentUser.getUserName());
                contract.setUpdaterId(currentUser.getId().toString());
                contract.setUpdateUser(currentUser.getUserName());
            } else {
                contract.setCreatorId("system");
                contract.setCreateUser("系统");
                contract.setUpdaterId("system");
                contract.setUpdateUser("系统");
            }
            
            contract.setIsDelete(0);
            
            // 保存合同
            this.save(contract);
            
            // 生成合同明细
            generateContractDetails(contractInnerId, relatedOrderNo);
            
            return new JsonResult<Contract3>().success(contract);
        } catch (Exception e) {
            log.error("生成采购合同失败", e);
            return new JsonResult<Contract3>().error("生成采购合同失败：" + e.getMessage());
        }
    }

    @Override
    public JsonResult<Boolean> updateContractStatus(String contractInnerId, Integer contractStatus) {
        try {
            if (StringUtils.isEmpty(contractInnerId)) {
                return new JsonResult<Boolean>().error("合同内码不能为空");
            }
            if (contractStatus == null) {
                return new JsonResult<Boolean>().error("合同状态不能为空");
            }
            
            Contract3 contract = this.getById(contractInnerId);
            if (contract == null) {
                return new JsonResult<Boolean>().error("合同不存在");
            }
            
            contract.setContractStatus(contractStatus);
            
            // 获取当前用户信息
            LoginUserInfo currentUser = UserContextUtil.getUser();
            if (currentUser != null) {
                contract.setUpdaterId(currentUser.getId().toString());
                contract.setUpdateUser(currentUser.getUserName());
            } else {
                contract.setUpdaterId("system");
                contract.setUpdateUser("系统");
            }
            contract.setUpdateTime(new Date());
            
            boolean result = this.updateById(contract);
            return new JsonResult<Boolean>().success(result);
        } catch (Exception e) {
            log.error("更新合同状态失败", e);
            return new JsonResult<Boolean>().error("更新合同状态失败：" + e.getMessage());
        }
    }

    @Override
    public void exportContractTemplate(String contractInnerId, HttpServletResponse response) {
        // TODO: 实现合同模板导出功能
        // 这里可以根据具体需求实现Excel或PDF导出
    }

    /**
     * 生成合同明细
     * @param contractInnerId 合同内码
     * @param relatedOrderNo 关联订单号
     */
    private void generateContractDetails(String contractInnerId, String relatedOrderNo) {
        try {
            // 查询订单明细
            QueryWrapper<PurchaseOrderDetail> detailWrapper = new QueryWrapper<>();
            detailWrapper.eq("purchase_order_id", relatedOrderNo);
            detailWrapper.eq("is_delete", 0);
            List<PurchaseOrderDetail> orderDetails = purchaseOrderDetailService.list(detailWrapper);
            
            if (orderDetails == null || orderDetails.isEmpty()) {
                log.warn("订单 {} 没有明细数据", relatedOrderNo);
                return;
            }
            
            // 生成合同明细
            List<ContractDetail3> contractDetails = new ArrayList<>();
            for (PurchaseOrderDetail orderDetail : orderDetails) {
                ContractDetail3 contractDetail = new ContractDetail3();
                contractDetail.setContractInnerId(contractInnerId);
                contractDetail.setRelatedOrderDetailId(orderDetail.getId());
                contractDetail.setProdId(orderDetail.getProdId());
                contractDetail.setProductName(""); // 产品名称需要从产品表关联查询
                contractDetail.setProductSpec(""); // 产品规格需要从产品表关联查询
                contractDetail.setInstallmentNo(1); // 默认分期批次为1
                contractDetail.setInstallmentExpectedDate(orderDetail.getDeliveryDate() != null ? 
                    orderDetail.getDeliveryDate() : new Date());
                contractDetail.setInstallmentQuantity(orderDetail.getQuantity());
                contractDetail.setInstallmentRatio(new BigDecimal("100.00")); // 默认100%
                contractDetail.setQuantity(orderDetail.getQuantity());
                contractDetail.setUnit(orderDetail.getUnit());
                contractDetail.setUnitPrice(orderDetail.getUnitPrice());
                contractDetail.setSubtotalAmount(orderDetail.getTotalAmount());
                contractDetail.setTaxFreeUnitPrice(orderDetail.getTaxFreeUnitPrice());
                contractDetail.setTaxFreeAmount(orderDetail.getTaxFreeAmount());
                contractDetail.setTaxRate(orderDetail.getTaxRate());
                contractDetail.setTaxAmount(orderDetail.getTaxAmount());
                contractDetail.setDeliveryTerms(orderDetail.getDeliveryTerms());
                contractDetail.setPickupPeriodStart(orderDetail.getDeliveryDate());
                contractDetail.setPickupPeriodEnd(orderDetail.getDeliveryDate());
                contractDetail.setRemark(orderDetail.getRemark());
                contractDetail.setIsDelete(0);
                contractDetail.setCreateTime(new Date());
                contractDetail.setUpdateTime(new Date());
                
                contractDetails.add(contractDetail);
            }
            
            // 批量保存合同明细
            if (!contractDetails.isEmpty()) {
                contractDetail3Dao.batchInsert(contractDetails);
                log.info("成功生成 {} 条合同明细", contractDetails.size());
            }
        } catch (Exception e) {
            log.error("生成合同明细失败", e);
            throw new RuntimeException("生成合同明细失败：" + e.getMessage());
        }
    }
    
    /**
     * 解析日期字符串为Date对象
     * @param dateStr 日期字符串
     * @return Date对象
     */
    private Date parseDate(String dateStr) {
        if (StringUtils.isEmpty(dateStr)) {
            return new Date();
        }
        try {
            return new java.text.SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
        } catch (Exception e) {
            return new Date();
        }
    }
}